package manager

import (
	"barge/pkg/util"
	"fmt"
	"github.com/pkg/errors"
	"strings"
)

type Ruler interface {
	Action([]*Rule)
}

type Rule struct {
	Name       string `toml:"name"`
	Action     string `toml:"action"`
	Type       string `toml:"type"`
	SourceRepo string `toml:"sourceRepo,omitempty"`
	TargetRepo string `toml:"targetRepo,omitempty"`
	Source     string `toml:"source"`
	Target     string `toml:"target"`
	Comment    string `toml:"comment"`
}

func (r *Rule) Tidy() {
	if r.SourceRepo != "" {
		r.Source = r.SourceRepo
		r.SourceRepo = ""
	}
	if r.TargetRepo != "" {
		r.Target = r.TargetRepo
		r.TargetRepo = ""
	}
	if r.Type == "" {
		r.Type = ActionInfoManager.GetActionInfo(r.Action).Type
	}
	if r.Comment == "" {
		r.Comment = ActionInfoManager.GetActionInfo(r.Action).Discript
	}
}

func (r *Rule) Validate() error {
	if !ActionInfoManager.IsActionSupport(r.Action) {
		return errors.New("action 不支持")
	}
	switch r.Action {
	case ActionReplace:
		if r.Source == "" && r.Target == "" {
			return errors.New("缺少 replaceAction 所需的信息")
		}
	}
	return nil
}

// ///////////ImageAction////////////////////
func (r *Rule) AsImageAction() ImageAction {
	switch r.Action {
	case ActionReplace:
		return ImageAct(r.ReplaceAction)
	case ActionEcho:
		return ImageAct(r.EchoAction)
	case ActionFeatureBundle:
		return ImageAct(r.FeatureBundleAction)
	default:
		return nil
	}
}

func (r *Rule) ReplaceAction(image *MultiArchImage) {
	image.Reference = ImageReference(strings.ReplaceAll(string(image.Reference), r.Source, r.Target))
}

func (r *Rule) EchoAction(image *MultiArchImage) {
	fmt.Println()
	fmt.Println("**********echo**********")
	fmt.Println(image.Reference)
	fmt.Println("**********echo**********")
	fmt.Println()
}

func (r *Rule) FeatureBundleAction(image *MultiArchImage) {
	if image.Features == nil {
		image.Features = make(map[ImageFeature]bool)
	}
	if strings.HasSuffix(image.Reference.Repo(), "bundle") {
		image.Features[ImageFeatureBundle] = true
	}
}

// ///////////PasswordAction////////////////////
func (r *Rule) AsPasswordAction() PasswordAction {
	switch r.Action {
	case ActionBase64:
		return PasswordAct(r.base64Action)
	}
	return nil
}

func (r *Rule) base64Action(p *Password) {
	if strings.HasPrefix(p.Raw, r.Source) || strings.HasSuffix(p.Raw, r.Target) {
		origin := strings.TrimPrefix(p.Raw, r.Source)
		origin = strings.TrimSuffix(origin, r.Target)
		res, err := util.DecodeBase64(origin)
		if err != nil {
			return
		}
		p.Raw = res
	}
}
